package com.leave.web.servlet;

import com.leave.context.AppContext;
import com.leave.entity.Classes;
import com.leave.entity.Course;
import com.leave.entity.Leave;
import com.leave.service.CourseService;
import com.leave.service.LeaveService;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.IOException;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

@WebServlet(name = "leaveServlet",urlPatterns = {"/leave"})
public class LeaveServlet extends HttpServlet {
    private final static String LEAVE_LIST = "student_index.jsp";
    private final static String LEAVE_AUDIT_LIST = "/WEB-INF/views/instructor/instructor_audit_leave.jsp";
    private final static String LEAVE_EXPORT_LIST = "/WEB-INF/views/instructor/instructor_export_leave.jsp";
    private final static String LEAVE_FORM = "student_form.jsp";
    private final Logger logger = LoggerFactory.getLogger(LeaveServlet.class);
    private LeaveService leaveService;
    private CourseService courseService;


    @Override
    public void init() throws ServletException {
        super.init();
        //从IoC容器获取实例化bean组件
        leaveService = AppContext.getBean(LeaveService.class);
        courseService=AppContext.getBean(CourseService.class);

    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String action = request.getParameter("action");
        HttpSession session = request.getSession();
        logger.info("request process starting" + action);
        Leave leave = new Leave();
        String leaveID = request.getParameter("leaveID");
        String stuNo = request.getParameter("stuNo");
        String courseID1 = request.getParameter("courseID");
        String dayNum = request.getParameter("dayNum");
        String reason = request.getParameter("reason");
        String opinion = request.getParameter("opinion");
        String status = request.getParameter("status");

        try {
            //2:调用userService完成处理,此处switch语句的语法要求jdk1.8以上。
            switch (action) {
                case "list":
                    List<Leave> leavelist = leaveService.listleave(null);
                    session.setAttribute("leavelist", leavelist);
                    request.getRequestDispatcher(LEAVE_LIST).forward(request, response);
                    break;
                case "listAudit":
                    List<Leave> leaveAuditList = leaveService.listleave(null);
                    for (Leave leaveB : leaveAuditList) {
                        leave.setStatus(leaveB.getStatus() == "0" ? "待审核" : (leaveB.getStatus() == "1" ? "同意" : "不同意"));
                    }
                    session.setAttribute("list", leaveAuditList);
                    request.getRequestDispatcher(LEAVE_AUDIT_LIST).forward(request, response);
                    break;
                case "listExport":
                    List<Leave> leaveExportList = leaveService.listleave(null);
                    for (Leave leaveC : leaveExportList) {
                        leave.setStatus(leaveC.getStatus() == "0" ? "待审核" : (leaveC.getStatus() == "1" ? "同意" : "不同意"));
                    }
                    session.setAttribute("list", leaveExportList);
                    request.getRequestDispatcher(LEAVE_EXPORT_LIST).forward(request, response);
                    break;
                case "export":
                    List<Leave> exportList = leaveService.listleave(null);

                    // 创建Excel工作簿
                    HSSFWorkbook workbook = new HSSFWorkbook();
                    Sheet sheet = workbook.createSheet("请假单");

                    // 创建表头
                    Row headerRow = sheet.createRow(0);
                    String[] columns = {"请假编号", "课程编号", "请假事由", "天数", "学号", "请假时间", "状态", "审核时间", "审核意见"};
                    for (int i = 0; i < columns.length; i++) {
                        Cell cell = headerRow.createCell(i);
                        cell.setCellValue(columns[i]);
                    }
                    // 填充数据行
                    int rowIndex = 1;
                    for (Leave leaveD : exportList) {
                        Date applyTime = leaveD.getApplyTime();
//                        System.out.println("apply="+applyTime);
                        Date auditTime = leaveD.getAuditTime();
//                        System.out.println("audit="+auditTime);

                        Row row = sheet.createRow(rowIndex++);
                        row.createCell(0).setCellValue(leaveD.getLeaveID());
                        row.createCell(1).setCellValue(leaveD.getCourseID());
                        row.createCell(2).setCellValue(leaveD.getReason());
                        row.createCell(3).setCellValue(leaveD.getDayNum());
                        row.createCell(4).setCellValue(leaveD.getStuNo());
                        row.createCell(5).setCellValue(leaveD.getApplyTime());
                        // 设置状态单元格的样式（颜色等）
                        Cell statusCell = row.createCell(6);
                        CellStyle greenStyle = workbook.createCellStyle();
                        greenStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
                        greenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                        CellStyle redStyle = workbook.createCellStyle();
                        redStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
                        redStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                        if (leaveD.getStatus().equals("1")) {
                            statusCell.setCellValue("同意");
                            statusCell.setCellStyle(greenStyle);
                        } else if (leaveD.getStatus().equals("2")) {
                            statusCell.setCellValue("不同意");
                            statusCell.setCellStyle(redStyle);
                        } else {
                            statusCell.setCellValue("待审核");
                        }
                        if (auditTime != null) {
//                            row.createCell(7).setCellValue(DateUtil.getExcelDate(auditTime, false));
                            row.createCell(7).setCellValue(leaveD.getAuditTime());
                        } else {
                            row.createCell(7).setCellValue("");
                        }
                        row.createCell(8).setCellValue(leaveD.getOpinion());
                    }

                    // 设置响应头，提示浏览器下载文件
                    response.setContentType("application/vnd.ms-excel");
                    response.setHeader("Content-Disposition", "attachment; filename=请假单.xls");

                    // 将Excel内容写入响应输出流
                    try (OutputStream outputStream = response.getOutputStream()) {
                        workbook.write(outputStream);
                    }
                    // 关闭工作簿
                    workbook.close();
                    request.setAttribute("successMessage", "导出请假名单成功！");
                    request.getRequestDispatcher(LEAVE_EXPORT_LIST).forward(request, response);
                    break;
                case "edit":
                    Leave leave1 = new Leave();
                    // 设置当前时间为 AuditTime
                    Date dateA = new Date();
                    Timestamp times = new Timestamp(dateA.getTime());

                    String status_01 = "0"; // 默认值为 0，表示待审核
                    if ("同意".equals(status)) {
                        status_01 = "1";
                    } else if ("不同意".equals(status)) {
                        status_01 = "2";
                    }
                    leave1.setLeaveID(leaveID);
                    leave1.setAuditTime(times);
                    leave1.setOpinion(opinion);
                    leave1.setStatus(status_01);
//                    System.out.println("leave1="+leave1);
//                    resolveRequestParameter(request,leave1);;
                    boolean successE = leaveService.editLeave(leave1);
                    if (successE) {
                        // 表单提交成功
                        request.setAttribute("successMessage", "审核请假申请成功！");
                    } else {
                        // 数据写入失败
                        request.setAttribute("errorMessage", "审核请假申请失败，请重试！");
                    }
                    request.getRequestDispatcher("leave?action=listAudit").forward(request, response);
                    break;
                case "LeaveID":
                    //获取当前的时间转格式
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                    String timestamp = sdf.format(new Date());
                    Random random = new Random();
                    int randomNumber = random.nextInt(1000);
                    String ID = timestamp + String.format("%03d", randomNumber);
                    session.setAttribute("leaveID", ID);
                    List<Course> courselist=courseService.listcourse(null);
                    session.setAttribute("course",courselist);
                    request.getRequestDispatcher(LEAVE_FORM).forward(request, response);
                    break;
                case "seek":
                    String courseID = request.getParameter("courseID");
                    System.out.println("courseID " + courseID);
                    List<Leave> leavelist1 = leaveService.seek(courseID);
                    session.setAttribute("leavelist", leavelist1);
                    request.getRequestDispatcher(LEAVE_LIST).forward(request, response);
                    break;
                case "seekAudit":
                    String classID = request.getParameter("classID");
                    List<Leave> leaves = new ArrayList<>();
                    leaves = leaveService.seekClassID(classID);
                    session.setAttribute("list", leaves);
                    request.getRequestDispatcher(LEAVE_AUDIT_LIST).forward(request, response);
                    break;
                case "seekExport":
                    String classID_01 = request.getParameter("classID");
                    String term = request.getParameter("term");
                    List<Leave> leaveA = new ArrayList<>();
                    if (classID_01 != null && !classID_01.isEmpty() && term == null || term.isEmpty()) {
                        // 仅根据班级ID查询
                        leaveA = leaveService.seekClassID(classID_01);
                    } else if (term != null && !term.isEmpty() && classID_01 == null || classID_01.isEmpty()) {
                        // 仅根据学期查询
                        leaveA = leaveService.seekTerm(term);
                    } else if (classID_01 != null && !classID_01.isEmpty() && term != null && !term.isEmpty()) {
                        leaveA = leaveService.seekByClassIDAndTerm(classID_01, term);
                    } else {
                        // 两者都为空，可能需要处理错误或返回所有记录（不推荐）
                        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "请提供班级ID或学期。");
                    }
                    session.setAttribute("list", leaveA);
                    request.getRequestDispatcher(LEAVE_EXPORT_LIST).forward(request, response);
                    break;
                case "delete":
//                    System.out.println("leaveID " + leaveID);
                    leaveService.deleteLeave(leaveID);
//                    System.out.println(12300 + leaveID);
                    request.getRequestDispatcher("leave?action=list").forward(request, response);
                    break;
                case "add":
                    // 检查必填项是否为空
                    if (leaveID == null || leaveID.isEmpty() ||
                            stuNo == null || stuNo.isEmpty() ||
                            courseID1 == null || courseID1.isEmpty() ||
                            dayNum == null || dayNum.isEmpty() ||
                            reason == null || reason.isEmpty()) {
                        // 如果有必填项为空，设置错误信息并转发回表单页面
                        request.setAttribute("errorMessage", "请填写所有必填项！");
                        request.getRequestDispatcher(LEAVE_FORM).forward(request, response);
                        return;
                    }
                    // 手动设置非日期字段
                    leave.setLeaveID(leaveID);
                    leave.setStuNo(stuNo);
                    leave.setCourseID(courseID1);
                    leave.setDayNum(dayNum);
                    leave.setReason(reason);
                    // 设置当前时间为 applyTime
                    Date date = new Date();
                    Timestamp timestamp1 = new Timestamp(date.getTime());
                    leave.setApplyTime(timestamp1);
                    // 调用 service 组件完成数据写入
                    boolean success = leaveService.addLeave(leave);
                    if (success) {
                        // 表单提交成功
                        request.setAttribute("successMessage", "表单已成功提交！");
                        request.getRequestDispatcher("leave?action=LeaveID").forward(request, response);
                    } else {
                        // 数据写入失败
                        request.setAttribute("errorMessage", "表单提交失败，请重试！");
                        request.getRequestDispatcher(LEAVE_FORM).forward(request, response);
                    }
            }


        } catch (ServletException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    private void resolveRequestParameter(HttpServletRequest req, Object bean) {
        Map<String, String[]> reqParameterMap = req.getParameterMap();
//        System.out.println("reqParameterMap+" + reqParameterMap);
        Map<String, String[]> propertiesMap = new HashMap<String, String[]>();
        try {
            for (Map.Entry<String, String[]> entry : reqParameterMap.entrySet()) {
                String name = entry.getKey();
                String[] values = entry.getValue();
                // 判断 request 参数是否对应 JavaBean 对象的属性
                Class<?> propertyType = PropertyUtils.getPropertyType(bean, name);
                if (propertyType != null) {
                    propertiesMap.put(name, values);
                }
            }
            // 转换为 POJO 对象 bean 的属性值
            BeanUtils.populate(bean, propertiesMap);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("The property name could not be found", e);
        }
    }
}
